package com.aizhixin.lab.docker.controller;

import com.aizhixin.lab.account.dto.AccountDTO;
import com.aizhixin.lab.account.service.AccountService;
import com.aizhixin.lab.company.domain.UserDomain;
import com.aizhixin.lab.company.service.UserService;
import com.aizhixin.lab.config.Config;
import com.aizhixin.lab.course.course.domain.ContainerExperimentInfoDomain;
import com.aizhixin.lab.course.course.service.TeacherChapterService;
import com.aizhixin.lab.docker.common.AuthUtilService;
import com.aizhixin.lab.docker.common.ExceptionAuth;
import com.aizhixin.lab.docker.common.ExceptionValidation;
import com.aizhixin.lab.docker.common.ReturnJsonData;
import com.aizhixin.lab.docker.core.ContainerConfig;
import com.aizhixin.lab.docker.domain.*;
import com.aizhixin.lab.docker.entity.ContainerToImages;
import com.aizhixin.lab.docker.entity.ImageInfo;
import com.aizhixin.lab.docker.entity.LastOperation;
import com.aizhixin.lab.docker.repository.ContainerToImagesRepository;
import com.aizhixin.lab.docker.service.ChapterExperimentService;
import com.aizhixin.lab.docker.service.DockerContainerService;
import com.aizhixin.lab.docker.service.DockerImageService;
import com.aizhixin.lab.docker.service.ImageInfoService;
import com.aizhixin.lab.docker.util.GetTokenUtils;
import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.TypeReference;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/api/v1/docker/Container")
@Api(value = "docker容器管理api", description = "docker容器管理")
public class DockerContainerController {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private AccountService authUtilService;
    @Autowired
    private DockerContainerService containerService;
    @Autowired
    private ChapterExperimentService chapterExperimentService;
    @Autowired
    private UserService userService;
    @Autowired
    private TeacherChapterService teacherChapterService;
    @Autowired
    private DockerImageService dockerImageService;
    @Autowired
    private DockerContainerService dockerContainerService;
    @Autowired
    private ImageInfoService imageInfoService;
    @RequestMapping(value = "/getList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "容器列表", httpMethod = "POST", notes = "容器列表<br><br><b>lwq</b>")
    public ReturnJsonData getList(@RequestHeader("Authorization") String token) {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        
        token = GetTokenUtils.getToken(accountDTO);
        FormData containerList = containerService.getContainerList(accountDTO.getUserName(), token);
        if (containerList.getErrno() != 0) {
            throw new ExceptionValidation(416, containerList.getErrmsg());
        }
        ArrayList<RContainers> rContainers = JSON.parseObject(containerList.getData().toString(), new TypeReference<ArrayList<RContainers>>() {
        });
        ArrayList<RContainers> newContainers = new ArrayList<>();
        int i = 0;
        if (rContainers.size()>0) {
            for (RContainers r : rContainers) {
                ArrayList<Container> newContainer = new ArrayList<>();
                if (r.getContainers()!=null && r.getContainers().size() > 0) {
                    for (Container c : r.getContainers()) {
                        if (i == 0) {
                            c.setName("master");
                            i++;
                        } else {
                            c.setName("slave" + i);
                            i++;
                        }
                        newContainer.add(c);
                    }
                }
                newContainers.add(r);
            }
        }
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setData(newContainers);
        return returnJsonData;
    }
    @RequestMapping(value = "/archive/{courseId}",method = RequestMethod.DELETE)
    @ApiOperation(value = "归档班课下实验",httpMethod = "DELETE",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ReturnJsonData archive(@RequestHeader("Authorization")String token,@ApiParam(value = "courseId 课程id",required = true)@PathVariable(value = "courseId")String courseId){
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }

        if (StringUtils.isEmpty(courseId)){
            throw new ExceptionValidation(417,"course id is null");
        }

        dockerContainerService.deleteAllByCourseId(courseId);
        ReturnJsonData<String> returnJsonData = new ReturnJsonData<>();
        returnJsonData.setCode(200);
        returnJsonData.setResult(Boolean.TRUE);
        returnJsonData.setData(null);
        return returnJsonData;
    }



    @RequestMapping(value = "/getStuContainer", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取学生正在进行的容器", httpMethod = "GET", notes = "获取学生正在进行的容器<br><br><b>lwq</b>")
    public ReturnJsonData getStuContainer(@RequestHeader("Authorization") String token,
                                          @ApiParam(value = "name", required = false) @RequestParam(value = "name") String name) {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        token = GetTokenUtils.getToken(accountDTO);
        FormData containerList = containerService.getContainerList(name, token);
        if (containerList.getErrno() != 0) {
            throw new ExceptionValidation(416, containerList.getErrmsg());
        }
        ArrayList<RContainers> rContainers = JSON.parseObject(containerList.getData().toString(), new TypeReference<ArrayList<RContainers>>() {
        });
        ArrayList<RContainers> newContainers = new ArrayList<>();
        int i = 0;
        if (rContainers.size()>0) {
            for (RContainers r : rContainers) {
                ArrayList<Container> newContainer = new ArrayList<>();
                if (r.getContainers()!=null && r.getContainers().size() > 0) {
                    for (Container c : r.getContainers()) {
                        if (i == 0) {
                            c.setName("master");
                            i++;
                        } else {
                            c.setName("slave" + i);
                            i++;
                        }
                        newContainer.add(c);
                    }
                }
                newContainers.add(r);
            }
        }
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setData(newContainers);
        return returnJsonData;
    }
    @RequestMapping(value = "/getListByImage", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取该镜像下的容器列表", httpMethod = "GET", notes = "获取该镜像下的容器列表<br><br><b>lwq</b>")
    public ReturnJsonData getListByImage(@RequestHeader("Authorization") String token,
                                         @ApiParam(value = "imageName", required = false) @RequestParam(value = "imageName") String imageName ) {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        token = GetTokenUtils.getToken(accountDTO);
        FormData containerList = containerService.getContainerListByImages(imageName, token);
        if (containerList.getErrno() != 0) {
            throw new ExceptionValidation(416, containerList.getErrmsg());
        }
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setData(containerList.getData());
        return returnJsonData;
    }

    @RequestMapping(value = "/deferSaveContainer", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "延迟保存", httpMethod = "POST", notes = "延迟保存<br><br><b>lwq</b>")
    public void deferSaveContainer(@RequestHeader("Authorization") String token,
                                   @ApiParam(value = "Container", required = false) @RequestBody ContainerDomainV2 domain) {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        token = GetTokenUtils.getToken(accountDTO);
//        containerService.deferSaveContainer(domain,accountDTO,token,containerConfig.getExpire());
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
    }
    @RequestMapping(value = "/runImage", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "运行镜像", httpMethod = "POST", notes = "运行镜像<br><br><b>lwq</b>")
    public ReturnJsonData runImage(@RequestHeader("Authorization") String token,
                                            @ApiParam(value = "Container", required = false) @RequestBody ContainerDomain domain) throws InterruptedException {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }

        domain.setOwner(accountDTO.getUserName());
        token = GetTokenUtils.getToken(accountDTO);
        FormData containerList = containerService.getContainerList(accountDTO.getUserName(), token);
        ArrayList<RContainers> rContainers = JSON.parseObject(containerList.getData().toString(), new TypeReference<ArrayList<RContainers>>() {
        });
        if (rContainers.size() > 0) {
            RContainers rContainers1 = rContainers.get(0);
            String name = rContainers1.getName();
            containerService.deleteContainer(name, token);
            Thread.sleep(10000L);
        }
        ImageInfo imageInfo = imageInfoService.getImageInfo(domain.getImageName());
        if (imageInfo==null){
            domain.setExpire(5400L);
            domain.setCount(1);
        }else {
            domain.setExpire(imageInfo.getExpire());
            domain.setCount(1);
            domain.setSpec(imageInfo.getSpec());
        }
        FormData allocate = containerService.allocate(domain, token);
        if (allocate.getErrno() != 0) {
            throw new ExceptionValidation(416, allocate.getErrmsg());
        }
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setData(allocate);
        return returnJsonData;
    }
    @RequestMapping(value = "/saveImage", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "保存镜像(在新的镜像上创建镜像)", httpMethod = "POST", notes = "保存镜像(在基础镜像上)<br><br><b>lwq</b>")
    public ReturnJsonData saveImage(@RequestHeader("Authorization") String token,
                                        @ApiParam(value = "Container", required = false) @RequestBody ContainerDomainV2 domain) {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        if (StringUtils.isEmpty(domain.getNewImageName())){
            ReturnJsonData returnJsonData = new ReturnJsonData<>();
            returnJsonData.setResult(false);
            returnJsonData.setData("请输入镜像名称");
            return returnJsonData;
        }
        token = GetTokenUtils.getToken(accountDTO);

        Boolean save = containerService.rootSave(domain, accountDTO, token);
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setResult(save);
        return returnJsonData;
    }
    @RequestMapping(value = "/getRunningExperiment", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "是否有正在运行的容器", httpMethod = "GET", notes = "是否有正在运行的容器<br><br><b>lwq</b>")
    public ReturnJsonData getRunningExperiment(@RequestHeader("Authorization") String token) {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        token = GetTokenUtils.getToken(accountDTO);
        Set<String> keys = redisTemplate.keys(accountDTO.getUserName()+":" + "*");
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        if (keys.size()==0){
            returnJsonData.setData(null);
            return returnJsonData;
        }
        ContainerExperimentInfoDomain containerExperimentInfoDomain =null;
        for (String s:keys){
            String[] split = s.split(":");
            containerExperimentInfoDomain = teacherChapterService.getExperimentInfo(Long.parseLong(split[1]));
        }
        returnJsonData.setData(containerExperimentInfoDomain);
        return returnJsonData;
    }
    @RequestMapping(value = "/allocateContainer", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "创建容器", httpMethod = "POST", notes = "创建容器<br><br><b>lwq</b>")
    public ReturnJsonData allocateContainer(@RequestHeader("Authorization") String token,
                                            @ApiParam(value = "Container", required = false) @RequestBody ContainerDomain domain) throws InterruptedException {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        domain.setOwner(accountDTO.getUserName());
        token = GetTokenUtils.getToken(accountDTO);
        
        FormData containerList = containerService.getContainerList(accountDTO.getUserName(), token);
        ArrayList<RContainers> rContainers = JSON.parseObject(containerList.getData().toString(), new TypeReference<ArrayList<RContainers>>() {
        });
        if (rContainers.size() > 0) {
            for (RContainers r:rContainers){
                String name = r.getName();
                containerService.deleteContainer(name, token);
            }
            Thread.sleep(10000L);
        }


        ImageInfo imageInfo = dockerImageService.getImageInfo(domain.getImageName());
        domain.setExpire(imageInfo.getExpire());
        domain.setCount(imageInfo.getVmNum());
        domain.setSpec(imageInfo.getSpec());
        if (domain.getIsNewExperiment()){
             containerService.allocate(domain, token);
        }else {
            containerService.allocateByVersion(domain,accountDTO.getId(),token);
        }

//        if (allocate.getErrno() != 0) {
//            throw new ExceptionValidation(416, allocate.getErrmsg());
//        }
        Set<String> keys = redisTemplate.keys(accountDTO.getUserName()+ "*");
        if (keys.size()>0) {
            redisTemplate.delete(keys);
        }
        String token1=accountDTO.getUserName()+":"+domain.getChapterId()+":"+new Date().getTime();
        redisTemplate.opsForValue().set(token1, domain.getCourseId()+"_"+accountDTO.getId(),domain.getExpire(), TimeUnit.SECONDS);
        containerService.deferSaveContainer(domain,accountDTO,token,domain.getExpire(),token1);
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setData("success");
        return returnJsonData;
    }
    @RequestMapping(value = "/allocateProjectContainer", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "创建容器(项目用)", httpMethod = "POST", notes = "创建容器(项目用)<br><br><b>lwq</b>")
    public ReturnJsonData allocateContainer(@RequestHeader("Authorization") String token,
                                            @ApiParam(value = "Container", required = false) @RequestBody ContainerProjectDomain domain) throws InterruptedException {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }

        token = GetTokenUtils.getToken(accountDTO);

        FormData containerList = containerService.getContainerList(accountDTO.getUserName(), token);
        ArrayList<RContainers> rContainers = JSON.parseObject(containerList.getData().toString(), new TypeReference<ArrayList<RContainers>>() {
        });
        if (rContainers.size() > 0) {
            for (RContainers r:rContainers){
                String name = r.getName();
                containerService.deleteContainer(name, token);
            }
            Thread.sleep(10000L);
        }

        ContainerDomain containerDomain = new ContainerDomain();
        ImageInfo imageInfo = dockerImageService.getImageInfo(domain.getImageName());
        containerDomain.setExpire(imageInfo.getExpire());
        containerDomain.setCount(imageInfo.getVmNum());
        containerDomain.setSpec(imageInfo.getSpec());
        containerDomain.setImageName(imageInfo.getImagesName());
        containerDomain.setOwner(accountDTO.getUserName());
        containerDomain.setCourseId(domain.getProjectId());
        if (domain.getIsNewExperiment()){
            containerService.allocate(containerDomain, token);
        }else {
            containerService.projectAllocateByVersion(containerDomain,accountDTO.getId(),token);
        }

//        if (allocate.getErrno() != 0) {
//            throw new ExceptionValidation(416, allocate.getErrmsg());
//        }
        Set<String> keys = redisTemplate.keys(accountDTO.getUserName() + "*");
        if (keys.size()>0) {
            redisTemplate.delete(keys);
        }
        String token1=accountDTO.getUserName()+"|"+domain.getProjectId()+new Date().getTime();
        redisTemplate.opsForValue().set(token1, domain.getProjectId()+"_"+accountDTO.getId(),domain.getExpire(), TimeUnit.SECONDS);
        containerService.deferSaveContainer(containerDomain,accountDTO,token,domain.getExpire(),token1);
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setData("success");
        return returnJsonData;
    }
    @RequestMapping(value = "/getStuList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取正在进行试验的学生", httpMethod = "GET", notes = "获取正在进行试验的学生<br><br><b>lwq</b>")
    public ReturnJsonData getStuName(@RequestHeader("Authorization") String token,
                                     @ApiParam(value = "courseId", required = false) @RequestParam String courseId) throws InterruptedException {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        Set<String> keys = redisTemplate.keys(courseId + ":" + "*");
        List<Long> longList=new ArrayList<>();
        for (String s:keys) {
            String[] split = s.split(":");
            longList.add(Long.parseLong(split[1]));
        }
        List<UserDomain> domains=new ArrayList<>();
        for(Long id:longList){
            UserDomain userInfo = userService.getUserInfo(id);
            domains.add(userInfo);
        }
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setData(domains);
        return returnJsonData;
    }
//    @RequestMapping(value = "/test111", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
//    @ApiOperation(value = "测试redis端口", httpMethod = "POST", notes = "测试redis端口")
//    public ReturnJsonData test111() {
//        Set<String> keys = redisTemplate.keys("306:" + "*");
//
//        ReturnJsonData returnJsonData = new ReturnJsonData<>();
//        returnJsonData.setData(keys);
//        return returnJsonData;
//    }
    @RequestMapping(value = "/saveContainer", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "学生保存镜像", httpMethod = "POST", notes = "学生保存镜像<br><br><b>lwq</b>")
    public ReturnJsonData saveContainer(@RequestHeader("Authorization") String token,
                                        @ApiParam(value = "Container", required = false) @RequestBody List<ContainerDomainV2> domain) {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        if (domain.size()==0){
            throw new ExceptionAuth(417, "镜像信息不能为空");
        }
        token = GetTokenUtils.getToken(accountDTO);
        ContainerDomainV2 containerDomainV2 = domain.get(0);
        dockerContainerService.deleteContainerToImage(containerDomainV2.getCourseId(),containerDomainV2.getChapterId(),accountDTO.getId());
        for (ContainerDomainV2 c:domain) {
            String save = containerService.save(c, accountDTO, token);
            containerService.saveImages(c, accountDTO, save);
        }
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setData("success");
        return returnJsonData;
    }
    @RequestMapping(value = "/saveProjectContainer", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "学生保存镜像(项目用)", httpMethod = "POST", notes = "学生保存镜像(项目用)<br><br><b>lwq</b>")
    public ReturnJsonData saveProjectContainer(@RequestHeader("Authorization") String token,
                                        @ApiParam(value = "Container", required = false) @RequestBody List<ContainerProjectDomainV2> domain) {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        if (domain.size()==0){
            throw new ExceptionAuth(417, "镜像信息不能为空");
        }
        token = GetTokenUtils.getToken(accountDTO);
        ContainerProjectDomainV2 containerDomainV2 = domain.get(0);
        dockerContainerService.deleteContainerToImage(containerDomainV2.getProjectId(),accountDTO.getId());
        for (ContainerProjectDomainV2 c:domain) {
            ContainerDomainV2 domainV2 = new ContainerDomainV2();
            domainV2.setCourseId(c.getProjectId());
            domainV2.setContainerName(c.getContainerName());
            domainV2.setContainerIp(c.getContainerIp());
            String save = containerService.save(domainV2, accountDTO, token);
            containerService.saveImages(domainV2, accountDTO, save);
        }
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setData("success");
        return returnJsonData;
    }

    @RequestMapping(value = "/deleteContainer", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "删除容器", httpMethod = "DELETE", notes = "删除容器<br><br><b>lwq</b>")
    public ReturnJsonData deleteContainer(@RequestHeader("Authorization") String token,
                                          @ApiParam(value = "containerName", required = false) @RequestParam(value = "containerName") String containerName,
                                          @ApiParam(value = "chapterId", required = false) @RequestParam(value = "chapterId",required = false) String chapterId) {
        Map<String, Object> result = new HashMap<String, Object>();
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        if (StringUtils.isEmpty(containerName)) {
            throw new ExceptionAuth(417, "containerName is null");
        }
        token = GetTokenUtils.getToken(accountDTO);
        FormData containerList = containerService.getContainerList(accountDTO.getUserName(), token);
        ArrayList<RContainers> rContainers = JSON.parseObject(containerList.getData().toString(), new TypeReference<ArrayList<RContainers>>() {
        });
        if (rContainers.size() > 0) {
            for (RContainers r:rContainers){
                String name = r.getName();
                containerService.deleteContainer(name, token);
            }

        }
//        if (formData.getErrno() != 0) {
//            throw new ExceptionValidation(416, formData.getErrmsg());
//        }
        Set<String> keys = redisTemplate.keys(accountDTO.getUserName()+ "*");
        if (keys.size()>0) {
            redisTemplate.delete(keys);
        }
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setCode(200);
        returnJsonData.setData("success");
        return returnJsonData;
    }
    @RequestMapping(value = "/deleteRunningContainer", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "删除容器(主页)", httpMethod = "DELETE", notes = "删除容器(主页)<br><br><b>lwq</b>")
    public ReturnJsonData deleteContainer(@RequestHeader("Authorization") String token,
                                          @ApiParam(value = "imageName", required = false) @RequestParam(value = "imageName") String imageName) {
        Map<String, Object> result = new HashMap<String, Object>();
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        if (StringUtils.isEmpty(imageName)) {
            throw new ExceptionAuth(417, "imageName is null");
        }
        token = GetTokenUtils.getToken(accountDTO);
        Set<String> keys = redisTemplate.keys(accountDTO.getUserName()+ "*");
        if (keys.size()>0) {
            redisTemplate.delete(keys);
        }
        FormData containerList = containerService.getContainerList(accountDTO.getUserName(), token);
        ArrayList<RContainers> rContainers = JSON.parseObject(containerList.getData().toString(), new TypeReference<ArrayList<RContainers>>() {
        });
        if (rContainers.size() > 0) {
            for (RContainers r:rContainers){
                String name = r.getName();
                containerService.deleteContainer(name, token);
            }
        }
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setCode(200);
        returnJsonData.setData(containerList.getRequestId());
        return returnJsonData;
    }
    @RequestMapping(value = "/deleteImagesContainer", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "管理端删除容器", httpMethod = "DELETE", notes = "管理端删除容器<br><br><b>lwq</b>")
    public ReturnJsonData deleteImagesContainer(@RequestHeader("Authorization") String token,
                                          @ApiParam(value = "containerName", required = false) @RequestParam(value = "containerName") String containerName,
                                          @ApiParam(value = "userName", required = false) @RequestParam(value = "userName") String userName) {
        Map<String, Object> result = new HashMap<String, Object>();
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        if (StringUtils.isEmpty(containerName)) {
            throw new ExceptionAuth(417, "containerName is null");
        }
        token = GetTokenUtils.getToken(accountDTO);
        FormData formData = containerService.deleteContainer(containerName, token);
        if (formData.getErrno() != 0) {
            throw new ExceptionValidation(416, formData.getErrmsg());
        }
        Set<String> keys = redisTemplate.keys(userName+":" + "*");
        if (keys.size()>0) {
            redisTemplate.delete(keys);
        }
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setCode(200);
        returnJsonData.setData(formData.getRequestId());
        return returnJsonData;
    }

    @RequestMapping(value = "/setConfigContainer", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "配置容器规格", httpMethod = "GET", notes = "配置容器规格<br><br><b>lwq</b>")
    public ReturnJsonData setConfigContainer(@RequestHeader("Authorization") String token,
                                             @ApiParam(value = "defaultSpecs", required = false) @RequestParam(value = "defaultSpecs") Integer defaultSpecs,
                                             @ApiParam(value = "overSold", required = false) @RequestParam(value = "overSold") Integer overSold) {
        Map<String, Object> result = new HashMap<String, Object>();
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        if (defaultSpecs == 0 || defaultSpecs == null) {
            throw new ExceptionAuth(417, "defaultSpecs is null");
        }
        if (overSold == 0 || overSold == null) {
            throw new ExceptionAuth(417, "overSold is null");
        }
        token = GetTokenUtils.getToken(accountDTO);
        FormData formData = containerService.setConfig(defaultSpecs, overSold, token);
        if (formData.getErrno() != 0) {
            throw new ExceptionValidation(416, formData.getErrmsg());
        }
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setCode(200);
        returnJsonData.setData(formData.getRequestId());
        return returnJsonData;

    }

    @RequestMapping(value = "/getConfigContainer", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取容器规格", httpMethod = "GET", notes = "获取容器规格<br><br><b>lwq</b>")
    public ReturnJsonData getConfigContainer(@RequestHeader("Authorization") String token,
                                             @ApiParam(value = "name", required = false) @RequestParam(value = "name") String name) {
        Map<String, Object> result = new HashMap<String, Object>();
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (Objects.isNull(accountDTO)) {
            throw new ExceptionAuth(401, "无权限");
        }
        token = GetTokenUtils.getToken(accountDTO);
        System.out.println(token);
//        FormData formData = containerService.getConfig(token);
//        if (formData.getErrno() != 0) {
//            throw new ExceptionValidation(416, formData.getErrmsg());
//        }
        ImageInfo imageInfo = dockerImageService.getImageInfo(name);
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        returnJsonData.setCode(200);
        returnJsonData.setData(imageInfo);
        return returnJsonData;
    }

    @RequestMapping(value = "/create/container/init", method = RequestMethod.POST)
    @ApiOperation(value = "初始化创建虚拟机(点击实验章节时调用)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ReturnJsonData createContainerV2(@RequestHeader("Authorization") String token, @RequestBody ContainerInfoDomainV3 domainV3) {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        if (StringUtils.isEmpty(domainV3.getChapterId())) {
            throw new ExceptionValidation(417, "chapter id is null");
        }
        if (StringUtils.isEmpty(domainV3.getCourseId())) {
            throw new ExceptionValidation(417, "course id is null");
        }
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        ContainerExperimentDomainV2 containerExperimentDomainV2 = new ContainerExperimentDomainV2();
        List<LastOperation> lastOperation = containerService.getLastOperation(domainV3.getCourseId(), accountDTO.getId());
        List<ContainerToImages> upExperiment = containerService.getUpExperiment(domainV3, accountDTO.getId());
        Boolean userContainer = containerService.getUserContainer(domainV3.getCourseId(), domainV3.getChapterId(), accountDTO.getUserName());
        if (userContainer) {
            containerExperimentDomainV2.setInfo("running");
            containerExperimentDomainV2.setExist(true);
        } else if (lastOperation.size()>0||upExperiment.size()>0) {
            containerExperimentDomainV2.setInfo("exist");
            containerExperimentDomainV2.setExist(true);
        } else {
            containerExperimentDomainV2.setInfo("success");
            containerExperimentDomainV2.setExist(false);
        }
        returnJsonData.setCode(200);
        returnJsonData.setData(containerExperimentDomainV2);
        returnJsonData.setResult(Boolean.TRUE);
        return returnJsonData;


    }
    @RequestMapping(value = "/create/container/projectInit", method = RequestMethod.POST)
    @ApiOperation(value = "初始化创建虚拟机(项目用)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ReturnJsonData containerProjectInit(@RequestHeader("Authorization") String token, @RequestBody ContainerInfoDomainV3 domainV3) {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }

        if (StringUtils.isEmpty(domainV3.getProjectId())) {
            throw new ExceptionValidation(417, "project id is null");
        }
        ReturnJsonData returnJsonData = new ReturnJsonData<>();
        ContainerExperimentDomainV2 containerExperimentDomainV2 = new ContainerExperimentDomainV2();
        List<LastOperation> lastOperation = containerService.getLastOperation(domainV3.getProjectId(), accountDTO.getId());
        List<ContainerToImages> upExperiment = containerService.getProjectUpExperiment(domainV3, accountDTO.getId());
        Boolean userContainer = containerService.getUserContainer(domainV3.getProjectId(), accountDTO.getUserName());
        if (userContainer) {
            containerExperimentDomainV2.setInfo("running");
            containerExperimentDomainV2.setExist(true);
        } else if (lastOperation.size()>0||upExperiment.size()>0) {
            containerExperimentDomainV2.setInfo("exist");
            containerExperimentDomainV2.setExist(true);
        } else {
            containerExperimentDomainV2.setInfo("success");
            containerExperimentDomainV2.setExist(false);
        }
        returnJsonData.setCode(200);
        returnJsonData.setData(containerExperimentDomainV2);
        returnJsonData.setResult(Boolean.TRUE);
        return returnJsonData;


    }

    @RequestMapping(value = "/container/experiment", method = RequestMethod.DELETE)
    @ApiOperation(value = "删除章节下实验", httpMethod = "DELETE", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ReturnJsonData deleteExperiment(@RequestHeader("Authorization") String token, @RequestBody ContainerExperimentDomain containerExperimentDomain) {
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        if (StringUtils.isEmpty(containerExperimentDomain.getChapterId())) {
            throw new ExceptionValidation(417, "chapter id is null");
        }
        if (StringUtils.isEmpty(containerExperimentDomain.getCourseId())) {
            throw new ExceptionValidation(417, "course id is null");
        }
        chapterExperimentService.deleteChapterExperiment(containerExperimentDomain, accountDTO.getId().toString());
        ReturnJsonData<String> returnJsonData = new ReturnJsonData<>();
        returnJsonData.setCode(200);
        returnJsonData.setResult(Boolean.TRUE);
        returnJsonData.setData("success");
        return returnJsonData;
    }
    @RequestMapping(value = "/getResourceList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "资源监控", httpMethod = "GET", notes = "资源监控<br><br><b>lwq</b>")
    public ResponseEntity<?> getResourceList(@RequestHeader("Authorization") String token) {
        Map<String, Object> result = new HashMap<String, Object>();
        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        token= GetTokenUtils.getToken(accountDTO);
        System.out.println(token);
        FormData formData = containerService.getResourceList(token);
        ArrayList<Monitor> monitors = JSON.parseObject(formData.getData().toString(), new TypeReference<ArrayList<Monitor>>() {
        });
         ArrayList<Monitor> newMonitors =new ArrayList<>();
        for (Monitor monitor :monitors){
            if (monitor.getIpaddress().length()<18){
                newMonitors.add(monitor);
            }
        }
        formData.setData(newMonitors);
        if (formData.getErrno()==0){
            result.put("success", Boolean.TRUE);
            result.put("data",formData.getData());
            return new ResponseEntity<Map<String, Object>>(result, HttpStatus.OK);
        }else {
            result.put("success", Boolean.FALSE);
            result.put("error",formData.getErrmsg());
            return new ResponseEntity<Map<String, Object>>(result, HttpStatus.OK);
        }

    }
    @RequestMapping(value = "/container/download",method = RequestMethod.GET)
    @ApiOperation(value = "下载容器中文件",httpMethod = "GET")
    public ResponseEntity<byte[]> downloadFile(@RequestHeader("Authorization")String token,
                                               @ApiParam("hostIp 容器id") @RequestParam(value = "hostIp") String hostIp,
                                               @ApiParam("dir 文件路径") @RequestParam("dir") String dir,
                                               @ApiParam("fileName 文件名加后缀") @RequestParam("fileName") String fileName,
                                               @ApiParam("port 文件端口号") @RequestParam("port") String port
    )
    {

        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        if (StringUtils.isEmpty(hostIp)){
            throw new ExceptionValidation(417,"container id is null");
        }
        if (StringUtils.isEmpty(dir)){
            throw new ExceptionValidation(417,"文件路径不能为空");
        }
        if (StringUtils.isEmpty(fileName)){
            throw new ExceptionValidation(417,"文件名不能为空");
        }
        if (StringUtils.isEmpty(port)){
            throw new ExceptionValidation(417,"文件端口不能为空");
        }
        ResponseEntity<byte[]> responseEntity = containerService.downloadFile(hostIp,port, dir, fileName);
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentDispositionFormData("attachment", fileName);
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        httpHeaders.set("X-MSG",responseEntity.getHeaders().get("X-MSG").get(0));
        httpHeaders.set("X-CAUSE",responseEntity.getHeaders().get("X-CAUSE").get(0));
        return new ResponseEntity<>(responseEntity.getBody(),httpHeaders, HttpStatus.OK);
    }
    @RequestMapping(value = "/container/upload",method = RequestMethod.POST)
    @ApiOperation(value = "文件上传",httpMethod = "POST",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ReturnJsonData<String>  uploadFile(@RequestHeader("Authorization")String token,
                                              @ApiParam("hostIp 容器id") @RequestParam(value = "hostIp") String hostIp,
                                              @ApiParam("dir 文件保存路径") @RequestParam("dir") String dir,
                                              @ApiParam("file 选择上传文件") @RequestParam("file") MultipartFile file,
                                              @ApiParam("port 文件端口号") @RequestParam("port") String port){

        AccountDTO accountDTO = authUtilService.getUserByToken(token);
        if (accountDTO == null) {
            throw new ExceptionAuth(401, "无权限");
        }
        if (StringUtils.isEmpty(hostIp)){
            throw new ExceptionValidation(417,"container id is null");
        }
        if (StringUtils.isEmpty(dir)){
            throw new ExceptionValidation(417,"文件路径不能为空");
        }
        if (StringUtils.isEmpty(port)){
            throw new ExceptionValidation(417,"文件端口不能为空");
        }
        ReturnJsonData<String> returnJsonData = new ReturnJsonData<>();
        try {
            ResponseEntity<Map> mapResponseEntity = containerService.uploadFile(hostIp,port, dir, file.getOriginalFilename(), file.getBytes());
            if (mapResponseEntity.getHeaders().get("X-MSG").get(0).equals("success")) {
                returnJsonData.setData("success");
            }else {
                returnJsonData.setData("fail");
            }
        } catch (IOException e) {
            e.printStackTrace();
            returnJsonData.setData("fail");
        }
        return returnJsonData;
    }
}
